﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using Core.BOL;
using Core.DAL;
using Core.Extentions;
using ScoutNET.ActionsResults;
using Core;
using System.Net;
using System.IO;

namespace ScoutNET.Controllers
{
    public class AgendaController : ApplicationController
    {
        private CalendarRepository cr = new CalendarRepository();
        private SectionRepository sr = new SectionRepository();
        private ConvocRepository cor = new ConvocRepository();
         
        #region Views
        //
        // GET: /Section/Agenda/Index/?00/?00
        public ActionResult Index(string systemName, int? month, int? year)
        {
            int m = (month == null) ? DateTime.Now.GetNowTimeByTimeZone().Month : (int)month;
            int y = (year == null) ? DateTime.Now.GetNowTimeByTimeZone().Year : (int)year;

            List<tSite_Calendar> lCalendar = cr.GetEventsBySystemNameAndDate(systemName, m, y);
            if (month == null && year == null)
            {
                if (lCalendar.Count > 0 && lCalendar.Last().StartDate < DateTime.Now.GetNowTimeByTimeZone())
                {
                    m = m + 1;
                    if (m > 12)
                    {
                        m = 1;
                        y = y + 1;
                    }
                    lCalendar = cr.GetEventsBySystemNameAndDate(systemName, m, y);
                }
            }

            List<DateTime> lMeetings = new List<DateTime>();
            foreach (tSite_Calendar cal in lCalendar)
            {
                DateTime calDate = cal.StartDate;
                while (calDate.Date <= cal.EndDate.Date)
                {
                    lMeetings.Add(calDate);
                    calDate = calDate.AddDays(1);
                }   
            }      
   

            ViewData["CurrentDate"] = new DateTime(y, m, 01);
            ViewData["lMeetings"] = lMeetings;

            DateTime currentDate = Convert.ToDateTime("01/" + m + "/" + y);
            string monthName = currentDate.ToString("MMMM");
            string sectionLabel = sr.GetSectionNameBySystemName(systemName);

            // Meta Tag
            ViewData["PageTitle"] = Resources.Agenda_Index_Title.Replace("[MONTH]", monthName + " " + y).Replace("[SECTION]", sectionLabel.ToLower());
            ViewData["PageDescription"] = Resources.Agenda_Index_Description.Replace("[SECTION]",sectionLabel);

            ViewData["SystemName"] = systemName;
            ViewData["UserType"] = UsersRepository.GetUserType(systemName);

            //Breadcrumb
            string[] saBreadcrumb = new String[2];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = Resources.Agenda_Index_Breadcrumb.Replace("[MONTH]", monthName).Replace("[SECTION]", sectionLabel.ToLower());
            ViewData["Breadcrumb"] = saBreadcrumb;

            ViewData["FirstEventYear"] = cr.GetFirstEventBySection(systemName).StartDate;
            ViewData["LastEventYear"] = cr.GetLastEventBySection(systemName).StartDate;

            ViewData["PreviousDate"] = currentDate.AddMonths(-1);
            ViewData["NextDate"] = currentDate.AddMonths(1);
            ViewData["CurrentMonth"] = monthName;
            ViewData["IsAdminUser"] = (UsersRepository.GetUserType((string)ViewData["SystemName"]) != UserType.User);

            
            return View(lCalendar);
        }

        //
        // GET: /Section/Agenda/Create
        [Authorize(Roles = "Animateur,C.U")]
        public ActionResult Create(string systemName)
        {
            // Redirect to admin section
            string adminSection = UsersRepository.GetAdminSection(systemName);
            UserType ut = UsersRepository.GetUserType(systemName);
            if (systemName != adminSection && ut != UserType.Administrator)
            {
                return RedirectToAction("Create", new { systemName = adminSection });
            }

            // Meta Tag
            string section = sr.GetSectionNameBySystemName(systemName).ToLower();
            ViewData["PageTitle"] = Resources.Agenda_Create_Title.Replace("[SECTION]", section);
            ViewData["PageDescription"] = Resources.Agenda_Create_Description.Replace("[SECTION]", section);

            ViewData["SystemName"] = systemName;
            ViewData["UserType"] = ut;

            //Breadcrumb
            string[] saBreadcrumb = new String[3];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Agenda_Index_Breadcrumb.Substring(0, Resources.Agenda_Index_Breadcrumb.IndexOf(" ", Resources.Agenda_Index_Breadcrumb.IndexOf(" ") + 1)).Replace("[SECTION]", section), "SectionIndex", "Index", "Agenda", new RouteValueDictionary(new { systemName = systemName }), null);
            saBreadcrumb[2] = Resources.Agenda_Create_Breadcrumb;
            ViewData["Breadcrumb"] = saBreadcrumb;

            ViewData["slEventType"] = GetEventTypeSelectList();
            ViewData["Convoc"] = GetConvocSelectList(systemName, cor, null); 

            return View();
        }

        //
        // POST: /Section/Agenda/Create
        [Authorize(Roles = "Animateur,C.U")]
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Create(string systemName, FormCollection fc)
        {
            // Redirect to admin section
            string adminSection = UsersRepository.GetAdminSection(systemName);
            UserType ut = UsersRepository.GetUserType(systemName);
            if (systemName != adminSection && ut != UserType.Administrator)
            {
                return RedirectToAction("Create", new { systemName = adminSection });
            }

            // Meta Tag
            string section = sr.GetSectionNameBySystemName(systemName).ToLower();
            ViewData["PageTitle"] = Resources.Agenda_Create_Title.Replace("[SECTION]", section);
            ViewData["PageDescription"] = Resources.Agenda_Create_Description.Replace("[SECTION]", section);

            ViewData["SystemName"] = systemName;
            ViewData["UserType"] = ut;

            //Breadcrumb
            string[] saBreadcrumb = new String[3];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Agenda_Index_Breadcrumb.Substring(0, Resources.Agenda_Index_Breadcrumb.IndexOf(" ", Resources.Agenda_Index_Breadcrumb.IndexOf(" ") + 1)).Replace("[SECTION]", section), "SectionIndex", "Index", "Agenda", new RouteValueDictionary(new { systemName = systemName }), null);
            saBreadcrumb[2] = Resources.Agenda_Create_Breadcrumb;
            ViewData["Breadcrumb"] = saBreadcrumb;
            
            if (ValidateNewMeeting(fc))
            {
                int SID = sr.GetSectionID(systemName);
                tSite_Calendar c = GetCalendar(fc, SID);
                cr.InsertMeeting(c);
                cr.Save();

                List<tSite_Calendar> lMeetings = cr.GetLastestInsertedEventBySystemName(systemName, 5);

                ViewData["SectionName"] = section;
                ViewData["ValidationMessage"] = Resources.Agenda_Create_Validation.Replace("[USERNAME]", User.Identity.Name.UppercaseFirst());
                return View("Validation", lMeetings);
            }
            else
            {
                ViewData["Convoc"] = GetConvocSelectList(systemName, cor, null);
                ViewData["slEventType"] = GetEventTypeSelectList(fc["EventType"]);

                return View();
            }
        }

        //
        // GET: /Section/Agenda/Edit/ID
        [Authorize(Roles = "Animateur,C.U")]
        public ActionResult Edit(string systemName, int id)
        {
            // Redirect to admin section
            string adminSection = UsersRepository.GetAdminSection(systemName);
            UserType ut = UsersRepository.GetUserType(systemName);
            if (systemName != adminSection && ut != UserType.Administrator)
            {
                return RedirectToAction("Edit", new { systemName = adminSection });
            }

            // Meta Tag
            tSite_Calendar c = cr.GetEventsById(id);
            string section = sr.GetSectionNameBySystemName(systemName).ToLower();
            ViewData["PageTitle"] = Resources.Agenda_Edit_Title.Replace("[TITLE]", c.Title);
            ViewData["PageDescription"] = Resources.Agenda_Edit_Description.Replace("[TITLE]", c.Title);

            ViewData["SystemName"] = systemName;
            ViewData["UserType"] = ut;

            //Breadcrumb
            string[] saBreadcrumb = new String[3];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Agenda_Index_Breadcrumb.Substring(0, Resources.Agenda_Index_Breadcrumb.IndexOf(" ", Resources.Agenda_Index_Breadcrumb.IndexOf(" ") + 1)).Replace("[SECTION]", section), "SectionIndex", "Index", "Agenda", new RouteValueDictionary(new { systemName = systemName }), null);
            saBreadcrumb[2] = Resources.Agenda_Edit_Breadcrumb.Replace("[TITLE]", c.Title);
            ViewData["Breadcrumb"] = saBreadcrumb;

            ViewData["slEventType"] = GetEventTypeSelectList(c.EventType.ToString());
            ViewData["Convoc"] = GetConvocSelectList(systemName, cor, c.CID);

            return View(c);
        }

        //
        // POST: /Section/Agenda/Edit/ID
        [Authorize(Roles = "Animateur,C.U")]
        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Edit(string systemName, int id, FormCollection fc)
        {
            EventType at = (EventType)int.Parse(fc["eventType"]);
            tSite_Calendar c = cr.GetEventsById(id);

            // Redirect to admin section
            string adminSection = UsersRepository.GetAdminSection(systemName);
            UserType ut = UsersRepository.GetUserType(systemName);
            if (systemName != adminSection && ut != UserType.Administrator)
            {
                return RedirectToAction("Edit", new { systemName = adminSection });
            }

            // Meta Tag
            string section = sr.GetSectionNameBySystemName(systemName).ToLower();
            ViewData["PageTitle"] = Resources.Agenda_Edit_Title.Replace("[TITLE]", c.Title);
            ViewData["PageDescription"] = Resources.Agenda_Edit_Description.Replace("[TITLE]", c.Title);

            ViewData["SystemName"] = systemName;
            ViewData["UserType"] = ut;

            //Breadcrumb
            string[] saBreadcrumb = new String[3];
            saBreadcrumb[0] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Master_Breadcrumb_Home, "Default", "Index", "Home", null, null);
            saBreadcrumb[1] = HtmlHelper.GenerateLink(this.ControllerContext.RequestContext, RouteTable.Routes, Resources.Agenda_Index_Breadcrumb.Substring(0, Resources.Agenda_Index_Breadcrumb.IndexOf(" ", Resources.Agenda_Index_Breadcrumb.IndexOf(" ") + 1)).Replace("[SECTION]", section), "SectionIndex", "Index", "Agenda", new RouteValueDictionary(new { systemName = systemName }), null);
            saBreadcrumb[2] = Resources.Agenda_Edit_Breadcrumb.Replace("[TITLE]", c.Title);
            ViewData["Breadcrumb"] = saBreadcrumb;

            if (ValidateNewMeeting(fc))
            {
                int SID = sr.GetSectionID(systemName);
                c = GetCalendar(fc, SID, c);
                cr.Save();

                List<tSite_Calendar> lMeetings = cr.GetLastestInsertedEventBySystemName(systemName, 5);
                
                ViewData["SectionName"] = section;
                ViewData["ValidationMessage"] = Resources.Agenda_Edit_Validation.Replace("[USERNAME]", User.Identity.Name.UppercaseFirst());
                return View("Validation", lMeetings);
            }

            ViewData["slEventType"] = GetEventTypeSelectList(c.EventType.ToString());
            ViewData["Convoc"] = GetConvocSelectList(systemName, cor, c.CID); 
            return View(c);
        }

        //
        // GET: /Section/Agenda/Delete
        [Authorize(Roles = "Animateur,C.U")]
        public ActionResult Delete(string systemName, int id) 
        {
            ViewData["Message"] = Resources.Agenda_Delete_Confirm;
            ViewData["ID"] = id.ToString();

            return View("Confirm");
        }

        //
        // POST: /Section/Agenda/Delete
        [Authorize(Roles = "Animateur,C.U")]
        [HttpPost]
        public ActionResult Delete(string systemName, FormCollection fc)
        {
            cr.DeleteMeeting(int.Parse(fc["id"]));
            cr.Save();

            return new EmptyResult();
        }

        public ActionResult iCal(string systemName)
        {
            List<tSite_Calendar> lCal = cr.GetNextEventsBySystemName(systemName, 5);

            return new IcalContentResult(lCal, systemName);
        }
        #endregion

        #region Methodes
        private tSite_Calendar GetCalendar(FormCollection fc, int SID)
        {
            return GetCalendar(fc, SID, null);
        }

        private tSite_Calendar GetCalendar(FormCollection fc, int SID, tSite_Calendar cEvent)
        {
            EventType et = (EventType)int.Parse(fc["eventType"]);

            tSite_Calendar c = (cEvent != null) ? cEvent : new tSite_Calendar();
            
            string startTime = string.Empty;
            string endTime = string.Empty;
            if (et == EventType.Other)
            {
                startTime = fc["startDate"].ToString() + " " + fc["startHour"].ToString() + ":" + fc["startMinutes"].ToString();
                endTime = fc["enddate"].ToString() + " " + fc["endHour"].ToString() + ":" + fc["endMinutes"].ToString();
            }
            else if (et == EventType.Normal || et == EventType.Respite)
            {
                startTime = fc["startDate"].ToString() + " 14:30";
                endTime = fc["startDate"].ToString() + " 18:00";
            }

            string title = Server.HtmlDecode(fc["title"]);
            if (et == EventType.Normal)
            {
                title = Resources.Agenda_Create_EventNormalTite;
            }
            else if (et == EventType.Respite)
            {
                title = Resources.Agenda_Create_EventRespiteTite;
            }

            string location = Server.HtmlDecode(fc["location"]);
            if (et == EventType.Normal)
            {
                location = Resources.Agenda_Create_EventNormalLocation;
            }
            else if (et == EventType.Respite)
            {
                location = string.Empty;
            }

            string description = Server.HtmlDecode(fc["description"]);
            if (et == EventType.Normal)
            {
                description = string.Empty;
            }
            else if (et == EventType.Respite)
            {
                description = Resources.Agenda_Create_EventRespiteDescription;
            }

            string CID = Server.HtmlDecode(fc["ddconvoc"]);
            if (et == EventType.Respite)
            {
                CID = string.Empty;
            }

            c.Title = title;
            c.Description = description;
            c.Location = location;
            c.InsertDate = DateTime.Now.GetNowTimeByTimeZone();
            c.SID = SID;
            c.StartDate = DateTime.Parse(startTime);
            c.EndDate = DateTime.Parse(endTime);
            c.EventType = (int)et;
            c.CID = (!string.IsNullOrEmpty(CID)) ? int.Parse(CID) : (int?)null;

            return c;
        }

        private bool ValidateNewMeeting(FormCollection fc)
        {
            EventType et = (EventType)int.Parse(fc["eventType"]);
 
            ModelState.SetModelValue("title", ValueProvider.GetValue("title"));
            ModelState.SetModelValue("location", ValueProvider.GetValue("location"));
            ModelState.SetModelValue("description", ValueProvider.GetValue("description"));
            ModelState.SetModelValue("ddconvoc", ValueProvider.GetValue("ddconvoc"));
            ModelState.SetModelValue("startDate", ValueProvider.GetValue("startDate"));
            ModelState.SetModelValue("endDate", ValueProvider.GetValue("endDate"));
            ModelState.SetModelValue("eventType", ValueProvider.GetValue("eventType"));

            ModelState.SetModelValue("startHour", ValueProvider.GetValue("startHour"));
            ModelState.SetModelValue("startMinutes", ValueProvider.GetValue("startMinutes"));
            ModelState.SetModelValue("endHour", ValueProvider.GetValue("endHour"));
            ModelState.SetModelValue("endMinutes", ValueProvider.GetValue("endMinutes"));

            if (String.IsNullOrEmpty(fc["title"]) && et == EventType.Other)
            {
                ModelState.AddModelError("title", Resources.Agenda_Create_Error_Title);
            }

            if (String.IsNullOrEmpty(fc["location"]) && et == EventType.Other)
            {
                ModelState.AddModelError("location", Resources.Agenda_Create_Error_Location);
            }

            DateTime startDate = new DateTime();
            DateTime endDate = new DateTime();

            string startTime = (et == EventType.Other) ? fc["startDate"].ToString() + " " + fc["startHour"].ToString() + ":" + fc["startMinutes"].ToString() : fc["startDate"].ToString();
            string endTime = fc["enddate"].ToString() + " " + fc["endHour"].ToString() + ":" + fc["endMinutes"].ToString();

            if (!DateTime.TryParse(startTime, out startDate))
            {
                ModelState.AddModelError("startdate", Resources.Agenda_Create_Error_StartDate);
            }
            if (!DateTime.TryParse(endTime, out endDate) && et == EventType.Other)
            {
                ModelState.AddModelError("enddate", Resources.Agenda_Create_Error_EndDate);
            }
            if (startDate > endDate && fc["meetingType"] == "3")
            {
                ModelState.AddModelError("_FORM", Resources.Agenda_Create_Error_Date);
            }
            if (String.IsNullOrEmpty(fc["description"]) && et == EventType.Other)
            {
                ModelState.AddModelError("description", Resources.Agenda_Create_Error_Description);
            }
            return ModelState.IsValid;
        }

        private SelectList GetConvocSelectList(string systemName, ConvocRepository cr, int? selectetdItem)
        {
            List<tSite_Convoc> lConvoc = cr.GetConvocBySystemName(systemName, 0, 5);
            var slConvoc = (from c in lConvoc
                            select new
                            {
                                ID = c.ID,
                                Title = c.StartDate.ToString("dd/MM/yyyy") + " - " + c.EndDate.ToString("dd/MM/yyyy")
                            }).ToList();

            return new SelectList(slConvoc, "ID", "Title", selectetdItem);
        }

        private SelectList GetEventTypeSelectList()
        {
            return GetEventTypeSelectList(string.Empty);
        }

        private SelectList GetEventTypeSelectList(string selectedValue)
        {
            Dictionary<string, string> eventTypes = new Dictionary<string, string>();
            eventTypes.Add("1", "Normal");
            eventTypes.Add("2", "Relâche");
            eventTypes.Add("3", "Autre");

            return new SelectList(eventTypes, "Key", "Value", selectedValue);
        }
        #endregion
    }
}
